import { reactive } from "vue";
import { type Entry, type LayEntry, BizDict, BizLayDict } from "jmash-core";

import type { DictTypeReq, DictTypeModel } from "@/api/dict/os-dict-type/types";
import { dictTypeApi } from "@/api/dict/os-dict-type/index";

import type {
  DictEntryModel,
  DictEntryReq,
} from "@/api/dict/os-dict-entry/types";
import { dictEntryApi } from "@/api/dict/os-dict-entry/index";

import type {
  DictLayEntryModel,
  DictLayEntryReq,
} from "@/api/dict/os-dict-lay-entry/types";
import { dictLayEntryApi } from "@/api/dict/os-dict-lay-entry/index";

/** 查询缓存字典键值对 */
export async function dictMapCache(
  typeCode: string,
  enable?: boolean
): Promise<DictEntryModel[]> {
  return new Promise<DictEntryModel[]>((resolve, reject) => {
    const dictKey: string = `dict_${typeCode}_${enable}`;
    let dictStr = sessionStorage.getItem(dictKey);
    if (dictStr) {
      resolve(JSON.parse(dictStr));
    }
    if (!dictStr) {
      if (typeof dictEntryApi.findList == "undefined") {
        console.error("dictTypeApi.findList is not defined.");
        return;
      }
      const req = { typeCode: typeCode, enable: enable } as DictEntryReq;
      dictEntryApi.findList(req).then(({ data }) => {
        let values = data.results as DictEntryModel[];
        dictStr = JSON.stringify(values);
        if (data && data.results != undefined) {
          sessionStorage.setItem(dictKey, dictStr);
        }
        resolve(values);
      });
    }
  });
}

//普通数据字典
export class EntryDict {
  typeCode: string;
  enable?: boolean;
  values: DictEntryModel[];
  constructor(typeCode: string, enable?: boolean) {
    this.typeCode = typeCode;
    this.enable = enable;
    this.values = reactive([]);
    this.useDictValues();
  }

  //加载数据字典.
  useDictValues(): Promise<DictEntryModel[]> {
    return new Promise<DictEntryModel[]>((resolve, reject) => {
      dictMapCache(this.typeCode, this.enable).then(
        (data: DictEntryModel[]) => {
          this.values.length = 0;
          this.values.push(...data);
          resolve(this.values);
        }
      );
    });
  }

  //获取字典值
  getDictValue(key: string): string {
    const entry = this.values.find((entry) => entry.dictCode === key);
    return entry?.dictName ? entry.dictName : "";
  }

  clearCache(): void {
    const dictKey: string = `dict_${this.typeCode}_${this.enable}`;
    sessionStorage.removeItem(dictKey);
  }
}

// DictTypeBizDict 类，继承 BizDict 并实现其方法
export class DictTypeBizDict extends BizDict {
  // 实现 useValues 方法
  useValues(): Promise<Entry[]> {
    return new Promise((resolve, reject) => {
      // 假设 dictTypeApi.findList 是一个返回 Promise 的函数
      if (typeof dictTypeApi.findList == "undefined") {
        console.error("dictTypeApi.findList is not defined.");
        resolve(this.values);
        return;
      }
      const req = { entryType: this.query } as DictTypeReq;
      dictTypeApi
        .findList(req)
        .then(({ data }) => {
          const items: DictTypeModel[] = data.results;
          this.values.length = 0;
          this.values.push(
            ...items.map(
              (item) => ({ key: item.typeCode, value: item.typeName }) as Entry
            )
          );
          resolve(this.values);
        })
        .catch(reject);
    });
  }
}

//层级字典 Code
export class EntryBizLayDict extends BizLayDict {
  // 实现 useValues 方法
  useValues(): Promise<LayEntry[]> {
    return new Promise((resolve, reject) => {
      if (typeof dictLayEntryApi.findList == "undefined") {
        console.error("dictLayEntryApi.findList is not defined.");
        resolve(this.values);
        return;
      }
      const req = { ...this.query } as DictLayEntryReq;
      dictLayEntryApi
        .findList(req)
        .then(({ data }) => {
          const items = data.results as DictLayEntryModel[];
          this.values.length = 0;
          this.values.push(...this.convertToLayEntryArray(items));
          resolve(this.values);
        })
        .catch(reject);
    });
  }

  convertToLayEntryArray(dictLayEntries: DictLayEntryModel[]): LayEntry[] {
    return dictLayEntries.map((dictLayEntry) => {
      return {
        value: dictLayEntry.dictCode,
        label: dictLayEntry.dictName,
        parentId: dictLayEntry.parentId || "",
        children: dictLayEntry.children
          ? this.convertToLayEntryArray(dictLayEntry.children)
          : [],
      };
    });
  }
}

//层级字典 ID
export class EntryIdBizLayDict extends BizLayDict {
  // 实现 useValues 方法
  useValues(): Promise<LayEntry[]> {
    return new Promise((resolve, reject) => {
      if (typeof dictLayEntryApi.findList == "undefined") {
        console.error("dictLayEntryApi.findList is not defined.");
        resolve(this.values);
        return;
      }
      const req = { ...this.query } as DictLayEntryReq;
      dictLayEntryApi
        .findList(req)
        .then(({ data }) => {
          const items = data.results as DictLayEntryModel[];
          this.values.length = 0;
          this.values.push(...this.convertToLayEntryArray(items));
          resolve(this.values);
        })
        .catch(reject);
    });
  }

  convertToLayEntryArray(dictLayEntries: DictLayEntryModel[]): LayEntry[] {
    return dictLayEntries.map((dictLayEntry) => {
      return {
        value: dictLayEntry.dictId,
        label: dictLayEntry.dictName,
        parentId: dictLayEntry.parentId || "",
        children: dictLayEntry.children
          ? this.convertToLayEntryArray(dictLayEntry.children)
          : [],
      };
    });
  }
}
